package com.rp.dao.remote;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import com.rp.dao.IProdutoEstabelecimentoDAO;
import com.rp.dao.ResultSetProcessor;
import com.rp.model.ProdutoEstabelecimento;
import com.rp.view.ItemListaPesquisaProduto;

public class ProdutoEstabelecimentoDAO extends AbstractDB implements
	IProdutoEstabelecimentoDAO {

    private static ProdutoEstabelecimentoDAO INSTANCE;

    private ProdutoEstabelecimentoDAO() {
    }

    public static ProdutoEstabelecimentoDAO get() {
	if (INSTANCE == null) {
	    INSTANCE = new ProdutoEstabelecimentoDAO();
	}
	return INSTANCE;
    }

    @Override
    public void insereValor(long produto, long estabelecimento, float valor,
	    long date) throws Throwable {
	preparedStatement = ConnectionFactory.get().createStatement();
	try {
	    preparedStatement
		    .executeUpdate("INSERT INTO produto_estabelecimento (produto,estabelecimento,valor, data_alteracao) VALUES('"
			    + Long.toString(produto)
			    + "',"
			    + estabelecimento
			    + ","
			    + valor
			    + ",'"
			    + new Timestamp(date).toString() + "');");
	} finally {
	    preparedStatement.close();
	}
    }

    @Override
    public void atualizaValor(long eanProduto, long cnpjEstabelecimento,
	    float valor, long date) throws Throwable {
	preparedStatement = ConnectionFactory.get().createStatement();
	try {
	    preparedStatement
		    .executeUpdate("UPDATE produto_estabelecimento SET valor = "
			    + valor
			    + ", data_alteracao = '"
			    + new Timestamp(date).toString()
			    + "' WHERE produto = '"
			    + Long.toString(eanProduto)
			    + "' AND estabelecimento = "
			    + cnpjEstabelecimento
			    + " AND data_alteracao < '"
			    + new Timestamp(date).toString() + "';");
	} finally {
	    preparedStatement.close();
	}
    }

    @Override
    public List<ItemListaPesquisaProduto> buscaPorProduto(long produto)
	    throws Throwable {
	List<ItemListaPesquisaProduto> data = new ArrayList<ItemListaPesquisaProduto>();
	preparedStatement = ConnectionFactory.get().createStatement();
	try {
	    resultSet = preparedStatement
		    .executeQuery("SELECT PE.id, E.NOME nome_estabelecimento, E.endereco endereco, PE.valor valor, PE.data_alteracao data_alteracao FROM produto_estabelecimento PE"
			    + " LEFT JOIN estabelecimento E ON PE.estabelecimento = E.id"
			    + " LEFT JOIN produto P ON  P.id = PE.produto WHERE PE.produto = '"
			    + Long.toString(produto) + "' ORDER BY valor;");
	    try {
		while (resultSet.next()) {
		    long id = resultSet.getLong(1);// id
		    String nome = resultSet.getString(2);
		    String endereco = resultSet.getString(3);
		    double valor = resultSet.getDouble(4);
		    Date data_alteracao = resultSet.getDate(5);
		    ItemListaPesquisaProduto item = new ItemListaPesquisaProduto(
			    nome, endereco, valor, data_alteracao);
		    data.add(item);
		}
	    } finally {
		resultSet.close();
	    }
	} finally {
	    preparedStatement.close();
	}
	return data;
    }

    @Override
    public ItemListaPesquisaProduto buscaPorProdutoEstabelecimento(
	    long produto, long estabelecimento) throws Throwable {
	ItemListaPesquisaProduto data = null;
	preparedStatement = ConnectionFactory.get().createStatement();
	try {
	    resultSet = preparedStatement
		    .executeQuery("SELECT PE.id, E.NOME nome_estabelecimento, E.endereco endereco, PE.valor valor, PE.data_alteracao data_alteracao FROM produto_estabelecimento PE"
			    + " LEFT JOIN estabelecimento E ON PE.estabelecimento = E.id"
			    + " LEFT JOIN produto P ON  P.id = PE.produto WHERE PE.produto = '"
			    + Long.toString(produto)
			    + "' AND PE.estabelecimento = "
			    + estabelecimento
			    + ";");
	    try {
		if (resultSet.next()) {
		    long id = resultSet.getLong(1);// id
		    String nome = resultSet.getString(2);
		    String endereco = resultSet.getString(3);
		    double valor = resultSet.getDouble(4);
		    Date data_alteracao = resultSet.getDate(5);
		    data = new ItemListaPesquisaProduto(nome, endereco, valor,
			    data_alteracao);
		}
	    } finally {
		resultSet.close();
	    }
	} finally {
	    preparedStatement.close();
	}
	return data;
    }

    public ResultSetProcessor<ProdutoEstabelecimento> buscarPendentes(
	    Calendar data) throws Throwable {
	final Statement preparedStatement = ConnectionFactory.get()
		.createStatement();
	final ResultSet rs = preparedStatement
		.executeQuery("SELECT * FROM produto_estabelecimento WHERE data_alteracao > '"
			+ new Timestamp(data.getTimeInMillis()).toString()
			+ "';");
	return new ResultSetProcessor<ProdutoEstabelecimento>() {
	    @Override
	    public ProdutoEstabelecimento process() throws Throwable {
		if (rs.next()) {
		    long produto = rs.getLong("produto");
		    long estabelecimento = rs.getLong("estabelecimento");
		    float valor = rs.getFloat("valor");
		    final Timestamp data = rs.getTimestamp("data_alteracao");
		    return new ProdutoEstabelecimento(produto, estabelecimento,
			    valor, data.getTime());
		}
		rs.close();
		preparedStatement.close();
		return null;
	    }
	};
    }

    public long count(Calendar data) throws Throwable {
	long count = 0;
	preparedStatement = ConnectionFactory.get().createStatement();
	resultSet = preparedStatement
		.executeQuery("SELECT count(*) FROM produto_estabelecimento WHERE data_alteracao > '"
			+ new Timestamp(data.getTimeInMillis()).toString()
			+ "';");
	if (resultSet.next()) {
	    count = resultSet.getInt(1);
	}
	return count;
    }

    @Override
    public void criarTabela1() throws Throwable {
	// TODO Auto-generated method stub

    }

}
